/*
 * Copyright Chen Wei
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.cathy.common;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 对字符串或字节数组使用MD5算法进行加密，返回32位长度的16进制字符串（大写或小写）
 * 
 * @author Chen Wei
 */
public final class MD5Util {
	
	/**
	 * 对字符串使用MD5算法进行加密，返回32位长度的16进制<b>小写</b>字符串
	 * <p>例如执行下列代码后，<code>hexPass</code> 的值为 <code>e10adc3949ba59abbe56e057f20f883e</code>
	 * <pre>
	 *  String hexPass = MD5Util.toHexString("123456");
	 * </pre> 
	 * 
	 * @param data 需要进行MD5加密的原始字符串，不允许为 <code>null</code> 或长度为0的 <b>空字符串</b>
	 * @return MD5加密后返回32位长度的16进制<b>小写</b>字符串
	 * @throws IllegalArgumentException 当输入参数 <code>data</code> 为 <code>null</code> 或 <b>空字符串</b> 时，抛出此异常
	 */
	public static String toHexString(String data) {
		if (data != null && !data.isEmpty()) {
			try {
				return toHexString(data.getBytes("UTF-8"));
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);//never happend
			}
		} else {
			throw new IllegalArgumentException("MD5 digest error. Could not digest empty data.");
		}
	}
	
	/**
	 * 对字符串使用MD5算法进行加密，返回32位长度的16进制<b>大写</b>字符串
	 * <p>例如执行下列代码后，<code>hexPass</code> 的值为 <code>E10ADC3949BA59ABBE56E057F20F883E</code>
	 * <pre>
	 *  String hexPass = MD5Util.toHexString("123456");
	 * </pre> 
	 * 
	 * @param data 需要进行MD5加密的原始字符串，不允许为 <code>null</code> 或长度为0的 <b>空字符串</b>
	 * @return MD5加密后返回32位长度的16进制<b>大写</b>字符串
	 * @throws IllegalArgumentException 当输入参数 <code>data</code> 为 <code>null</code> 或 <b>空字符串</b> 时，抛出此异常
	 */
	public static String toUpperCaseHexString(String data) {
		return toHexString(data).toUpperCase();
	}
	
	/**
	 * 对字节数组使用MD5算法进行加密，返回32位长度的16进制<b>小写</b>字符串
	 * <p>例如执行下列代码后，<code>hexPass</code> 的值为 <code>6ac1e56bc78f031059be7be854522c4c</code>
	 * <pre>
	 *  byte[] data = new byte[]{1, 2, 3, 4 ,5 ,6};
	 *  String hexPass = MD5Util.toHexString(data);
	 * </pre>
	 * 
	 * @param data 需要进行MD5加密的原始字符串，不允许为 <code>null</code> 或长度为0的 <b>空数组</b>
	 * @return MD5加密后返回32位长度的16进制<b>小写</b>字符串
	 */
	public static String toHexString(byte[] data) {
		if (data != null && data.length > 0) {
			try {
				MessageDigest md = MessageDigest.getInstance("MD5");
				byte[] digestData = md.digest(data);
				return (new BigInteger(1, digestData)).toString(16);
			} catch (Exception e) {
				throw new RuntimeException(e);//never happend
			}
		} else {
			throw new IllegalArgumentException("MD5 digest error. Could not digest empty data.");
		}
	}
	
	public static String toUpperCaseHexString(byte[] data) {
		return toHexString(data).toUpperCase();
	}
	
	public static void main(String[] args) {
		byte[] data = new byte[]{1, 2, 3, 4 ,5 ,6};
		System.out.println(MD5Util.toHexString(data));
	}

}
